//
//  TSCVCPhotoEditor.m
//  Tsc_IOS
//
//  Created by Rio on 15-9-3.
//  Copyright (c) 2015年 idream. All rights reserved.
//
// 因为IOS系统自带的UIImagePickerController，无法裁剪正方形的图片（一般用于用户头像），更没有办法裁剪诸如4:3、2:1这样特殊尺寸的图片。查阅了相关资料，发现苹果官方文档（https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/CameraAndPhotoLib_TopicsForIOS/Articles/PickinganItemfromthePhotoLibrary.html#//apple_ref/doc/uid/TP40010408-SW1），及大家普遍的做法（http://stackoverflow.com/questions/9041732/set-dimensions-for-uiimagepickercontroller-move-and-scale-cropbox）都是建议你设计自己的图片裁剪器，来实现特殊尺寸的裁剪。
// 实现原理：使用UIImageView，其边界就是裁剪框的尺寸。当用户在UIImageView中放大/缩小图片，图片的全部（或者部分）出现在裁剪框内的部分，就是裁剪后的图片。

#define PHOTO_EDITOR_SCROLL_VIEW_PADDING 0.0f // 调整scrollView与边界元素之间的padding（默认：0）


#import "TSCVCPhotoEditor.h"
#import "TSCConstants.h"
#import "TSCMyUIUtil.h"
#import "TSCMyClickBtn.h"
#import "TSCMyImageUtil.h"


@implementation TSCVCPhotoEditor {
    UIImage * _image; // 传入的参数：UIImage
    UIImageView * _ivPhoto; // 图片UIImageView
    UIScrollView * _sv; // scrollView
    
    ScreenOrientation _screenOrientationWhenInit; // 初始时，屏幕是否为竖屏（注：如果不为竖屏，则一定为横屏）
    NSArray * _svConstraintsArrWhenInit; // 初始时，scrollView应该使用的约束
    NSArray * _svConstraintsArrAfterRotate; // 当屏幕旋转后（旋转至和初始时不是一个方向时），scrollView应该使用的约束
    
    CGFloat _svWHWhenInit; // 初始时，scrollView的宽高
    CGFloat _svWHAfterRotate; // 当屏幕旋转后（旋转至和初始时不是一个方向时），scrollView的宽高
}

#pragma mark 校验并获取输入
- (void) getVCInput:(NSNotificationCenter *)notification {
    [super getVCInput:notification];
    
    _image = [_inputDic objectForKey:AEKI_UIIMAGE] ;
    
    NSAssert(_image != nil, @"%s: 输入参数必须包括：%@！", __FUNCTION__, AEKI_UIIMAGE);
}

+ (id)vcPhotoEditorWithStoryboard {
    UIStoryboard * sb = [UIStoryboard storyboardWithName:UI_STORYBOARD_NAME_MAIN bundle:[NSBundle mainBundle]];
    return [sb instantiateViewControllerWithIdentifier:UI_VC_NAME_PHOTO_EDITOR];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    // 数据准备
    
    // 判断并记录，初始时，屏幕是否为竖屏
    _screenOrientationWhenInit = [TSCMyUIUtil getScreenOrientationNow];
    
    // 计算sv的“正方形”宽高
    CGRect statusBarFrame = [TSCMyUIUtil getStatusBarFrame]; // 获得statusBar的高度
    CGRect naviBarFrame = [TSCMyUIUtil getNavigationBarFrame:self]; // 获得naviBar的高度
    _svWHWhenInit = MIN(UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT - statusBarFrame.size.height - naviBarFrame.size.height - _tfInfo.frame.size.height) - PHOTO_EDITOR_SCROLL_VIEW_PADDING;
    _svWHAfterRotate = MIN(UI_SCREEN_HEIGHT, UI_SCREEN_WIDTH - statusBarFrame.size.height - naviBarFrame.size.height - _tfInfo.frame.size.height) - PHOTO_EDITOR_SCROLL_VIEW_PADDING;
    
    
    // 设置自定义导航栏
    _nbc = [[TSCMyNaviBarCreator alloc]initAndCreateWithViewController:self hasGoBackButton:YES goBackVC:nil hasAppLogo:YES titleResourceKey:@"title_crop_photo" iconResourceNameArray:[NSArray arrayWithObjects:@"ic_submit_reply_96x96.png", nil] iconClickedListenerArray:[NSArray arrayWithObjects: [self createFinishEditingBlock], nil]];
    
    // 设置sv（scrollView）
    _sv = [[UIScrollView alloc]init];
    //    [TSCMyUIUtil setUIRoundBorder:_sv radius:0.0 borderColor:COLOR_MT borderWidth:1.0f];
    _sv.contentSize = _image.size; // 注：sv的大小，同UIImage的大小
    _sv.delegate = self;
    _sv.maximumZoomScale = [self getScrollViewMaximumZoomScale]; // 设置最大缩放比例（注：屏幕旋转后，由于svWH变化，所以需要重置）
    _sv.minimumZoomScale = [self getScrollViewMinimumZoomScale]; // 设置最小缩放比例（注：屏幕旋转后，由于svWH变化，所以需要重置）
    [_viBg addSubview:_sv];
    
    // 计算scrollView在初始时，及屏幕旋转后，这两种情况下的全部约束
    _svConstraintsArrWhenInit = [NSArray arrayWithObjects:
                                 // 宽度
                                 [NSLayoutConstraint constraintWithItem:_sv attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:_svWHWhenInit],
                                 // 高度
                                 [NSLayoutConstraint constraintWithItem:_sv attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:_svWHWhenInit],
                                 nil];
    _svConstraintsArrAfterRotate = [NSArray arrayWithObjects:
                                    // 宽度
                                    [NSLayoutConstraint constraintWithItem:_sv attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:_svWHAfterRotate],
                                    // 高度
                                    [NSLayoutConstraint constraintWithItem:_sv attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:_svWHAfterRotate],
                                    nil];
    
    // 约束
    // sv
    // 添加宽高约束
    _sv.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint constraintWithItem:_sv attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_viBg attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f].active = YES; // 水平父元素居中
    [NSLayoutConstraint constraintWithItem:_sv attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_viBg attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f].active = YES; // 垂直父元素居中
    // 添加当前约束
    [NSLayoutConstraint activateConstraints:_svConstraintsArrWhenInit];
    // 禁用旋转后的约束
    // 注：旋转后的约束，由屏幕旋转事件触发
    [NSLayoutConstraint deactivateConstraints:_svConstraintsArrAfterRotate];
    
    
    // 初始化UIImageView
    //    _ivPhoto = [[UIImageView alloc]initWithImage:_image]; // 注：不要使用该方法，而应该使用下面的方法！
    _ivPhoto = [[UIImageView alloc]initWithImage:[TSCMyImageUtil adjustImageOrientation:_image]]; // 注：对于UIImagePickerController通过拍照获得的UIImage，必须使用TSCMyImageUtil->adjustImageOrientation()来进行调整，否则，当设备拍照时为竖屏，则UIImagePickerController返回的UIImage被拉长了（变窄了）！将导致后续的裁剪错误！
    _ivPhoto.contentMode = UIViewContentModeCenter;
    [_sv addSubview:_ivPhoto];
    
    
    // 初始化底部说明文字
    _tfInfo.enabled = NO; // 不可编辑
    _tfInfo.backgroundColor = COLOR_MT_DIALOG_MODAL;
    _tfInfo.text = NSLocalizedString(@"content_photo_editor", nil);
    _tfInfo.textColor = [UIColor whiteColor];
    _tfInfo.font = [TSCMyUIUtil getSystemDefaultFont];
    
    
    // 注册事件——监听屏幕转动
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
    
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */

#pragma mark 私有方法

// 获得sv在放大时的比例值
/* private */ - (CGFloat) getScrollViewMaximumZoomScale {
    
    NSAssert(_screenOrientationWhenInit != ScreenOrientationUnknow && _svWHWhenInit != 0 && _svWHAfterRotate != 0, @"[E]%s: 图片编辑器VC中，获得scrollView的最大缩放比时，没有初始化：_screenOrientationWhenInit、_svWHWhenInit、_svWHAfterRotate！", __FUNCTION__);
    
    // 判断当前屏幕方向，与初始时是否一致，从而获得当前scrollView的宽高
    ScreenOrientation screenOrientationNow = [TSCMyUIUtil getScreenOrientationNow];
    CGFloat svWH;
    if (screenOrientationNow == _screenOrientationWhenInit) {
        svWH = _svWHWhenInit;
    } else {
        svWH = _svWHAfterRotate;
    }
    
    // 当图片大于sv
    if (_image.size.width > svWH && _image.size.height > svWH) {
        return 2.0f;
    }
    // 当图片小于sv
    else {
        return svWH / MIN(_image.size.width, _image.size.height);
    }
}

// 获得sv在缩小时的比例值
/* private */ - (CGFloat) getScrollViewMinimumZoomScale {
    
    NSAssert(_screenOrientationWhenInit != ScreenOrientationUnknow && _svWHWhenInit != 0 && _svWHAfterRotate != 0, @"[E]%s: 图片编辑器VC中，获得scrollView的最大缩放比时，没有初始化：_screenOrientationWhenInit、_svWHWhenInit、_svWHAfterRotate！", __FUNCTION__);
    
    // 判断当前屏幕方向，与初始时是否一致，从而获得当前scrollView的宽高
    ScreenOrientation screenOrientationNow = [TSCMyUIUtil getScreenOrientationNow];
    CGFloat svWH;
    if (screenOrientationNow == _screenOrientationWhenInit) {
        svWH = _svWHWhenInit;
    } else {
        svWH = _svWHAfterRotate;
    }
    
    // 当图片大于sv
    if (_image.size.width > svWH && _image.size.height > svWH) {
        return svWH / MIN(_image.size.width, _image.size.height);
    }
    // 当图片小于sv
    else {
        return 1.0f;
    }
}

/* private */ - (BBtnClickedListener) createFinishEditingBlock {
    return ^(TSCMyClickBtn * btn){
        
        // 判断当前屏幕方向，与初始时是否一致，从而获得当前scrollView的宽高
        ScreenOrientation screenOrientationNow = [TSCMyUIUtil getScreenOrientationNow];
        CGFloat svWH;
        if (screenOrientationNow == _screenOrientationWhenInit) {
            svWH = _svWHWhenInit;
        } else {
            svWH = _svWHAfterRotate;
        }
        
        // 计算原始的（缩放前）的contentOffset
        CGFloat zoomScale = _sv.zoomScale;
        CGPoint contentOffsetNow = _sv.contentOffset;
        CGPoint contentOffsetOriginal = CGPointMake(contentOffsetNow.x / zoomScale, contentOffsetNow.y / zoomScale);
        
        // 计算裁剪区域
        CGRect rect = CGRectMake(contentOffsetOriginal.x, contentOffsetOriginal.y, svWH / zoomScale, svWH / zoomScale);
        
        // 生成裁剪后的UIImage
        UIImage * imageEdited = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([
                                                                                        // 注：这里需要将拍照后的相片调整为正常方向（orientation）
                                                                                        //                                                                                        [TSCMyImageUtil scaleImage:_image toSize:_image.size]
                                                                                        [TSCMyImageUtil adjustImageOrientation:_image]
                                                                                        CGImage], rect)];
        
        // 执行图片编辑完成之后的回调
        if (_callbackAfterImageEdited) {
            _callbackAfterImageEdited(self, imageEdited);
        }
    };
}


#pragma mark delegate

// 监听屏幕旋转
- (void)orientChange:(NSNotification *)noti {
    // 获得屏幕当前的方向
    ScreenOrientation screenOrientationNow = [TSCMyUIUtil getScreenOrientationNow];
    
    // 初始时的屏幕方向，和旋转后的屏幕方向一致，则应用whenInit中的约束
    if (screenOrientationNow == _screenOrientationWhenInit) {
        for (NSLayoutConstraint * ct in _svConstraintsArrAfterRotate) {
            ct.active = NO;
        }
        for (NSLayoutConstraint * ct in _svConstraintsArrWhenInit) {
            ct.active = YES;
        }
    }
    // 初始时的屏幕方向，和旋转后的屏幕方向不一致，则应用afterRotate中的约束
    else {
        for (NSLayoutConstraint * ct in _svConstraintsArrWhenInit) {
            ct.active = NO;
        }
        for (NSLayoutConstraint * ct in _svConstraintsArrAfterRotate) {
            ct.active = YES;
        }
    }
    
    // 重置sv最大、最小缩放比例（注：屏幕旋转后，由于svWH变化，所以需要重置）
    _sv.maximumZoomScale = [self getScrollViewMaximumZoomScale];
    _sv.minimumZoomScale = [self getScrollViewMinimumZoomScale];
}

// 当捕获到缩放手势时，告诉系统具体要缩放哪一个view
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _ivPhoto;
}

//- (void) scrollViewDidZoom:(UIScrollView *)scrollView {
//    NSLog(@"zoomScale:%f, x:%f, y:%f", _sv.zoomScale, _sv.contentOffset.x, _sv.contentOffset.y);
//}

@end
